home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 October / Macformat17.cdr / Shareware City / Developers / shutdown-fx-20-c / sfx control app ƒ / Shell ƒ / prefs.c < prev    next >
Text File  |  1994-07-11  |  10KB  |  339 lines

  1. /**********************************************************************\
  2.  
  3. File:        prefs.c
  4.  
  5. Purpose:    This module handles creating/opening/closing/updating
  6.             the preference file, and copying the preference file
  7.             data into our globals (and back).
  8.  
  9. This program is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU General Public License as published by
  11. the Free Software Foundation; either version 2 of the License, or
  12. (at your option) any later version.
  13.  
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. GNU General Public License for more details.
  18.  
  19. You should have received a copy of the GNU General Public License
  20. along with this program in a file named "GNU General Public License".
  21. If not, write to the Free Software Foundation, 675 Mass Ave,
  22. Cambridge, MA 02139, USA.
  23.  
  24. \**********************************************************************/
  25.  
  26. #include "Folders.h"
  27. #include "prefs.h"
  28. #include "help.h"
  29. #include "dialogs.h"
  30. #include "environment.h"
  31. #include "program globals.h"
  32.  
  33. #define        PREFS_FILE_NAME            "\pShutdown FX prefs"
  34. #define        PREFS_TYPE                'pref'
  35. #define        PREFS_HEADER_VERSION    9
  36.  
  37. typedef struct
  38. {
  39.     short            maintopic;
  40.     short            subtopic;
  41.     char            onrestart;
  42.     char            onshutdown;
  43.     char            israndom;
  44.     char            unused;
  45.     short            moduleIndex;
  46. } PrefStruct;
  47.  
  48. /* internal globals for use in prefs.c only */
  49. static    Boolean            gCanSavePrefs;
  50. static    PrefStruct        thePrefs;
  51. static    long            gPrefsFilePos;
  52.  
  53. /*-----------------------------------------------------------------------------------*/
  54. /* internal stuff for prefs.c                                                        */
  55.  
  56. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID);
  57. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID);
  58. void ClosePrefsFile(short prefsFileID);
  59. enum PrefErrorTypes GetNextPrefs(short prefsFileID);
  60. enum PrefErrorTypes SavePrefs(short prefsFileID);
  61. enum PrefErrorTypes CheckVersion(short prefsFileID);
  62. enum PrefErrorTypes GetFileID(void);
  63. enum PrefErrorTypes CheckFileID(void);
  64. enum PrefErrorTypes Virgin(short prefsFileID);
  65. void DefaultPrefs(void);
  66. void CopyGlobalsToPrefs(void);
  67. void CopyPrefsToGlobals(void);
  68.  
  69. void SaveThePrefs(void)
  70. /* standard procedure callable from anywhere to save prefs to disk (if possible) */
  71. {
  72.     short            prefsFileID;
  73.     
  74.     if (gCanSavePrefs)        /* if we had no errors in PreferencesInit() */
  75.     {
  76.         OpenPrefsFile(&prefsFileID);    /* open the prefs file */
  77.         CopyGlobalsToPrefs();            /* copy global variables to prefs struct */
  78.         SavePrefs(prefsFileID);            /* save prefs to disk */
  79.         ClosePrefsFile(prefsFileID);    /* close prefs file */
  80.     }
  81. }
  82.  
  83. enum PrefErrorTypes PreferencesInit(void)
  84. {
  85.     short            prefsFileID;
  86.     short            err;
  87.     
  88.     gCanSavePrefs=FALSE;    /* assume the worst and maybe you'll be pleasantly surprised */
  89.     err=OpenPrefsFile(&prefsFileID);    /* open prefs file (or create new one) */
  90.     if (err!=prefs_allsWell)
  91.     {
  92.         if ((err==prefs_diskReadErr) || (err==prefs_diskWriteErr) || (err==prefs_virginErr))
  93.             ClosePrefsFile(prefsFileID);    /* close & abort if error or if new prefs */
  94.         return err;
  95.     }
  96.     
  97.     err=CheckVersion(prefsFileID);        /* check prefs version */
  98.     if (err!=prefs_allsWell)
  99.     {
  100.         ClosePrefsFile(prefsFileID);
  101.         return err;
  102.     }
  103.     
  104.     GetFPos(prefsFileID, &gPrefsFilePos);
  105.     err=GetNextPrefs(prefsFileID);        /* get prefs struct from file */
  106.     if (err==prefs_noMorePrefsErr)        /* or not */
  107.         return (Virgin(prefsFileID));    /* can't find our prefs struct */
  108.         
  109.     if (err!=prefs_allsWell)            /* any other error, just abort */
  110.     {
  111.         ClosePrefsFile(prefsFileID);
  112.         return err;
  113.     }
  114.     
  115.     CopyPrefsToGlobals();                /* copy prefs struct to program globals */
  116.     ClosePrefsFile(prefsFileID);        /* close prefs file */
  117.     gCanSavePrefs=TRUE;
  118.     return prefs_allsWell;                /* piece o' cake */
  119. }
  120.  
  121. void PrefsError(enum PrefErrorTypes err)
  122. {
  123.     Str255            tempStr;
  124.     
  125.     switch (err)
  126.     {
  127.         case prefs_diskReadErr:
  128.         case prefs_diskWriteErr:
  129.         case prefs_cantCreatePrefsErr:
  130.         case prefs_cantOpenPrefsErr:
  131.         case prefs_versionNotSupportedErr:
  132.             DefaultPrefs();                    /* use default prefs if error */
  133.             gCanSavePrefs=FALSE;            /* don't bother trying to save prefs later */
  134.             GetIndString(tempStr, 128, err);    /* get error string from .rsrc file */
  135.             ParamText(tempStr, "\p", "\p", "\p");
  136.             PositionDialog('ALRT', largeAlert);
  137.             StopAlert(largeAlert, 0L);        /* display error alert */
  138.             break;
  139.         default:
  140.             gCanSavePrefs=TRUE;                /* can save prefs to disk later if needed */
  141.             break;
  142.     }
  143. }
  144.  
  145. enum PrefErrorTypes OpenPrefsFile(short *prefsFileID)
  146. {
  147.     short            thisFile;
  148.     OSErr            isHuman;
  149.     short            vRefNum;
  150.     long            dirID;
  151.     FSSpec            prefsFile;
  152.     FInfo            prefsInfo;
  153.     Boolean            newPrefs;
  154.     unsigned char    *name=PREFS_FILE_NAME;
  155.     
  156.     newPrefs=FALSE;
  157.     /* find vRefNum and dirID of preferences folder, creating it if necessary */
  158.     isHuman=FindFolder(kOnSystemDisk, 'pref', kCreateFolder, &vRefNum, &dirID);
  159.     
  160.     if (isHuman!=noErr)        /* screwed up already?!? */
  161.         return prefs_cantOpenPrefsErr;
  162.     if (gHasFSSpecs)
  163.     {
  164.         isHuman=FSMakeFSSpec(vRefNum, dirID, name, &prefsFile);    /* make FSSpec out of it */
  165.         if (isHuman!=noErr)
  166.         {
  167.             if (isHuman==fnfErr)    /* FSSpec is valid, but prefs file does not exist */
  168.             {
  169.                 isHuman=FSpCreate(&prefsFile, CREATOR, PREFS_TYPE, 0);    /* so create it */
  170.                 if (isHuman!=noErr)                                        /* or not */
  171.                     return prefs_cantCreatePrefsErr;
  172.                 newPrefs=TRUE;        /* signal that prefs file is new */
  173.             }
  174.             else return prefs_cantOpenPrefsErr;
  175.         }
  176.         isHuman=FSpOpenDF(&prefsFile, fsRdWrPerm, &thisFile);    /* open prefs file */
  177.         *prefsFileID=thisFile;        /* store file reference number */
  178.         if (isHuman!=noErr)
  179.             return prefs_cantOpenPrefsErr;
  180.     }
  181.     else
  182.     {
  183.         /* try to open prefs file */
  184.         isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  185.         *prefsFileID=thisFile;
  186.         if (isHuman!=noErr)
  187.         {
  188.             if (isHuman==fnfErr)    /* prefs file does not exist */
  189.             {
  190.                 /* ...so create it */
  191.                 if (HCreate(vRefNum, dirID, name, CREATOR, PREFS_TYPE)!=noErr)
  192.                     return prefs_cantCreatePrefsErr;
  193.                 prefsInfo.fdType=PREFS_TYPE;
  194.                 prefsInfo.fdCreator=CREATOR;
  195.                 prefsInfo.fdFlags=0;
  196.                 prefsInfo.fdLocation.h=prefsInfo.fdLocation.v=0;
  197.                 prefsInfo.fdFldr=0;
  198.                 
  199.                 /* set file info of newly created prefs file */
  200.                 if (HSetFInfo(vRefNum, dirID, name, &prefsInfo)!=noErr)
  201.                     return prefs_cantCreatePrefsErr;
  202.                 
  203.                 /* NOW open the prefs file */
  204.                 isHuman=HOpen(vRefNum, dirID, name, fsRdWrPerm, &thisFile);
  205.                 *prefsFileID=thisFile;        /* store file reference number */
  206.                 if (isHuman!=noErr)
  207.                     return prefs_cantOpenPrefsErr;
  208.                 newPrefs=TRUE;                /* signal that prefs file is new */
  209.             }
  210.             else return prefs_cantOpenPrefsErr;
  211.         }
  212.     }
  213.     if (newPrefs)
  214.         return SetupNewPrefsFile(*prefsFileID);        /* needs initial setup if new */
  215.     
  216.     return prefs_allsWell;
  217. }
  218.  
  219. enum PrefErrorTypes SetupNewPrefsFile(short prefsFileID)
  220. /* this writes the prefs version number to the newly created prefs file, so we can
  221.    tell if the prefs file was created by a later version of the program and is
  222.    therefore in a format that we don't support -- forward compatability!  what
  223.    a concept! */
  224. {
  225.     long            count;
  226.     short            temp;
  227.     
  228.     gPrefsFilePos=2L;
  229.     if (SetEOF(prefsFileID, 2L)!=noErr)    /* set length of prefs file to 2 */
  230.         return prefs_diskWriteErr;
  231.     
  232.     SetFPos(prefsFileID, 1, 0L);
  233.     temp=PREFS_HEADER_VERSION;            /* get the prefs version (hardcoded) */
  234.     count=2L;
  235.     if (FSWrite(prefsFileID, &count, &temp)!=noErr)        /* write prefs version */
  236.         return prefs_diskWriteErr;        
  237.     
  238.     return Virgin(prefsFileID);            /* be gentle; it's our first time */
  239. }
  240.  
  241. void ClosePrefsFile(short prefsFileID)
  242. {
  243.     FSClose(prefsFileID);                /* close file on disk */
  244.     FlushVol(0L, kOnSystemDisk);        /* flush volume to write out new info */
  245. }
  246.  
  247. enum PrefErrorTypes GetNextPrefs(short prefsFileID)
  248. {
  249.     OSErr        isHuman;
  250.     long        count;
  251.     
  252.     count=sizeof(thePrefs);
  253.     isHuman=FSRead(prefsFileID, &count, &thePrefs);        /* get next prefs struct */
  254.     if (isHuman==eofErr)    /* no more left */
  255.         return prefs_noMorePrefsErr;
  256.     if (isHuman!=noErr)        /* some other error */
  257.         return prefs_diskReadErr;
  258.     
  259.     return prefs_allsWell;
  260. }
  261.  
  262. enum PrefErrorTypes SavePrefs(short prefsFileID)
  263. {
  264.     long        oldEOF;
  265.     long        count;
  266.     
  267.     GetEOF(prefsFileID, &oldEOF);
  268.     if (gPrefsFilePos>=oldEOF)        /* add new prefs struct onto end of prefs file */
  269.     {
  270.         if (SetEOF(prefsFileID, oldEOF+sizeof(thePrefs))!=noErr)
  271.             return prefs_diskWriteErr;
  272.     }
  273.     
  274.     SetFPos(prefsFileID, 1, gPrefsFilePos);        /* set position inside prefs file */
  275.     count=sizeof(thePrefs);
  276.     /* write prefs struct and return appropriate error code */
  277.     return (FSWrite(prefsFileID, &count, &thePrefs)!=noErr) ?
  278.         prefs_diskWriteErr : prefs_allsWell;
  279. }
  280.  
  281. enum PrefErrorTypes CheckVersion(short prefsFileID)
  282. {
  283.     OSErr            isHuman;
  284.     long            count;
  285.     short            temp;
  286.     
  287.     count=2L;
  288.     isHuman=FSRead(prefsFileID, &count, &temp);        /* get prefs version */
  289.     if (isHuman!=noErr)
  290.         return prefs_diskReadErr;
  291.     if (temp>PREFS_HEADER_VERSION)                    /* too new */
  292.         return prefs_versionNotSupportedErr;
  293.     if (temp<PREFS_HEADER_VERSION)                    /* old; overwrite */
  294.         return SetupNewPrefsFile(prefsFileID);
  295.     
  296.     return prefs_allsWell;
  297. }
  298.  
  299. enum PrefErrorTypes Virgin(short prefsFileID)
  300. {
  301.     short            err;
  302.     
  303.     DefaultPrefs();
  304.     CopyGlobalsToPrefs();
  305.     err=SavePrefs(prefsFileID);
  306.     
  307.     return (err==prefs_allsWell) ? prefs_virginErr : err;
  308. }
  309.  
  310. void DefaultPrefs(void)
  311. {
  312.     gMainTopicShowing=gSubTopicShowing=0;
  313.     gOnRestart=gOnShutdown=gChooseRandom=0xFF;
  314.     gModuleIndex=-1;
  315. }
  316.  
  317. void CopyGlobalsToPrefs(void)
  318. {
  319.     thePrefs.maintopic=gMainTopicShowing;
  320.     thePrefs.subtopic=gSubTopicShowing;
  321.     
  322.     thePrefs.onrestart=gOnRestart;
  323.     thePrefs.onshutdown=gOnShutdown;
  324.     thePrefs.israndom=gChooseRandom;
  325.     thePrefs.unused=0x00;
  326.     thePrefs.moduleIndex=gModuleIndex;
  327. }
  328.  
  329. void CopyPrefsToGlobals(void)
  330. {
  331.     gMainTopicShowing=thePrefs.maintopic;
  332.     gSubTopicShowing=thePrefs.subtopic;
  333.     
  334.     gOnRestart=thePrefs.onrestart;
  335.     gOnShutdown=thePrefs.onshutdown;
  336.     gChooseRandom=thePrefs.israndom;
  337.     gModuleIndex=thePrefs.moduleIndex;
  338. }
  339.